home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / Miro_Downloader.exe / databasesanity.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2007-11-12  |  7.2 KB  |  210 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. """Sanity checks for the databases.
  5.  
  6. This module is deprecated: database sanity checking is done by the
  7. checkConstraints method on DDBObjects.  This is a better way to do things
  8. because it will catch errors right when we save objects, instead of some
  9. unknown point in the future.  We still have this code around, because it's
  10. used to do sanity checks on old databases.
  11.  
  12. """
  13. import item
  14. import feed
  15. import util
  16. import guide
  17.  
  18. class DatabaseInsaneError(Exception):
  19.     pass
  20.  
  21.  
  22. class SanityTest(object):
  23.     '''Base class for the sanity test objects.'''
  24.     
  25.     def checkObject(self, object):
  26.         '''checkObject will be called for each object in the object list.
  27.         If there is an error return a string describing it.  If not return
  28.         None (or just let the function hit the bottom).
  29.         '''
  30.         raise NotImplementedError()
  31.  
  32.     
  33.     def finished(self):
  34.         '''Called when we reach the end of the object list, SanityTest
  35.         subclasses may implement additional checking here.'''
  36.         pass
  37.  
  38.     
  39.     def fixIfPossible(self, objectList):
  40.         """Subclasses may implement this method if it's possible to fix broken
  41.         databases.  The default implementation just raises a
  42.         DatabaseInsaneError.
  43.         """
  44.         raise DatabaseInsaneError()
  45.  
  46.  
  47.  
  48. class PhontomFeedTest(SanityTest):
  49.     """Check that no items reference a Feed that isn't around anymore."""
  50.     
  51.     def __init__(self):
  52.         self.feedsInItems = set()
  53.         self.topLevelFeeds = set()
  54.         self.parentsInItems = set()
  55.         self.topLevelParents = set()
  56.  
  57.     
  58.     def checkObject(self, obj):
  59.         if isinstance(obj, item.Item):
  60.             if obj.feed_id is not None:
  61.                 self.feedsInItems.add(obj.feed_id)
  62.             
  63.             if obj.parent_id is not None:
  64.                 self.parentsInItems.add(obj.parent_id)
  65.             
  66.             if obj.isContainerItem in (None, True):
  67.                 self.topLevelParents.add(obj.id)
  68.             
  69.         elif isinstance(obj, feed.Feed):
  70.             self.topLevelFeeds.add(obj.id)
  71.         
  72.  
  73.     
  74.     def finished(self):
  75.         pass
  76.  
  77.     
  78.     def fixIfPossible(self, objectList):
  79.         for i in reversed(xrange(len(objectList))):
  80.             if isinstance(objectList[i], item.Item) and objectList[i].feed_id is not None and objectList[i].feed_id not in self.topLevelFeeds:
  81.                 del objectList[i]
  82.                 continue
  83.             if isinstance(objectList[i], item.Item) and objectList[i].parent_id is not None and objectList[i].parent_id not in self.topLevelParents:
  84.                 del objectList[i]
  85.                 continue
  86.         
  87.  
  88.  
  89.  
  90. class SingletonTest(SanityTest):
  91.     '''Check that singleton DB objects are really singletons.
  92.  
  93.     This is a baseclass for the channle guide test, manual feed test, etc.
  94.     '''
  95.     
  96.     def __init__(self):
  97.         self.count = 0
  98.  
  99.     
  100.     def checkObject(self, obj):
  101.         if self.objectIsSingleton(obj):
  102.             self.count += 1
  103.             if self.count > 1:
  104.                 return 'Extra %s in database' % self.singletonName
  105.             
  106.         
  107.  
  108.     
  109.     def finished(self):
  110.         if self.count == 0:
  111.             pass
  112.         
  113.  
  114.     
  115.     def fixIfPossible(self, objectList):
  116.         if self.count == 0:
  117.             return None
  118.         else:
  119.             seenObject = False
  120.             for i in reversed(xrange(len(objectList))):
  121.                 if self.objectIsSingleton(objectList[i]):
  122.                     if seenObject:
  123.                         del objectList[i]
  124.                     else:
  125.                         seenObject = True
  126.                 seenObject
  127.             
  128.  
  129.  
  130.  
  131. class ChannelGuideSingletonTest(SingletonTest):
  132.     singletonName = 'Channel Guide'
  133.     
  134.     def objectIsSingleton(self, obj):
  135.         if isinstance(obj, guide.ChannelGuide):
  136.             pass
  137.         return obj.url is None
  138.  
  139.  
  140.  
  141. class ManualFeedSingletonTest(SingletonTest):
  142.     singletonName = 'Manual Feed'
  143.     
  144.     def objectIsSingleton(self, obj):
  145.         if isinstance(obj, feed.Feed):
  146.             pass
  147.         return isinstance(obj.actualFeed, feed.ManualFeedImpl)
  148.  
  149.  
  150.  
  151. def checkSanity(objectList, fixIfPossible = True, quiet = False, reallyQuiet = False):
  152.     """Do all sanity checks on a list of objects.
  153.  
  154.     If fixIfPossible is True, the sanity checks will try to fix errors.  If
  155.     this happens objectList will be modified.
  156.  
  157.     If fixIfPossible is False, or if it's not possible to fix the errors
  158.     checkSanity will raise a DatabaseInsaneError.
  159.  
  160.     If quiet is True, we print to the log instead of poping up an error dialog
  161.     on fixable problems.  We set this when we are converting old databases,
  162.     since sanity errors are somewhat expected.
  163.  
  164.     If reallyQuiet is True, won't even print out a warning on fixable
  165.     problems.
  166.  
  167.     Returns True if the database passed all sanity tests, false otherwise.
  168.     """
  169.     tests = set([
  170.         PhontomFeedTest(),
  171.         ChannelGuideSingletonTest(),
  172.         ManualFeedSingletonTest()])
  173.     errors = []
  174.     failedTests = set()
  175.     for obj in objectList:
  176.         for test in tests:
  177.             rv = test.checkObject(obj)
  178.             if rv is not None:
  179.                 errors.append(rv)
  180.                 failedTests.add(test)
  181.                 continue
  182.         
  183.         tests = tests.difference(failedTests)
  184.     
  185.     for test in tests:
  186.         rv = test.finished()
  187.         if rv is not None:
  188.             errors.append(rv)
  189.             failedTests.add(test)
  190.             continue
  191.     
  192.     if errors:
  193.         errorMsg = 'The database failed the following sanity tests:\n'
  194.         errorMsg += '\n'.join(errors)
  195.         if fixIfPossible:
  196.             if not quiet:
  197.                 util.failed(when = 'While checking database', details = errorMsg)
  198.             elif not reallyQuiet:
  199.                 print 'WARNING: Database sanity error'
  200.                 print errorMsg
  201.             
  202.             for test in failedTests:
  203.                 test.fixIfPossible(objectList)
  204.             
  205.         else:
  206.             raise DatabaseInsaneError(errorMsg)
  207.     
  208.     return errors == []
  209.  
  210.